{*******************************************************************************
* The contents of this file are used with permission, subject to the Mozilla   *
* Public License Version 1.1 (the "License"); you may not use this file except *
* in compliance with the License. You may obtain a copy of the License at      *
* http://www.mozilla.org/MPL/                                                  *
*                                                                              *
* Software distributed under the License is distributed on an "AS IS" basis,   *
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for *
* the specific language governing rights and limitations under the License.    *
*                                                                              *
* The Original Code is distributed as part of the "mediate" product and is     *
* Copyright (C) @home media limited. All Rights Reserved.                      *
*                                                                              *
* Email: support@athomemedia.co.uk                                             *
* Web:   http://www.athomemedia.co.uk                                          *
*******************************************************************************}

unit PluginWindows;

interface

uses Classes, AHMTypes, UIObjects, Viewport, Colours, Fills, XMLHelper;

{$IFDEF DESIGNER}
const
  // Property categories and hints for designer
  CAT_PLUGINWINDOW = 'Plugin Window';
  HINT_WIDTH = 'specifies width for the plugin window';
  HINT_HEIGHT = 'specifies height for the plugin window';
  HINT_COLOUR = 'specifies the name of a colour item to use for the window background';
  HINT_FILL = 'specifies the name of a fill item to use for shading the window';
{$ENDIF}

type
  TAHMPluginWindow = class(TAHMUIDisplayObject)
  private
    FColour: TAHMColour;
    FFill: TAHMAbstractFill;
  protected
    procedure ClearProperties; override;
  public
    constructor Create(const Name: String); override;
    procedure Render(Control: TObject; iX, iY, iWidth, iHeight: Single); override;
    procedure SeedObject; override;
    procedure Assign(Source: TPersistent); override;
    procedure SaveXMLBody(Lines: TStrings); override;
    procedure ParseFromXML(XML: TAHMXMLHelper); override;
    procedure BuildProperties(Properties: TAHMUIPropertyList); override;
  published
    property Colour: TAHMColour read FColour write FColour;
    property Fill: TAHMAbstractFill read FFill write FFill;
    // Publish inherited properties
    property VirtualWidth;
    property VirtualHeight;
  end;

  TAHMPluginWindowList = class(TAHMUIObjectList)
  private
  protected
  public
    constructor Create; override;
    function AddPluginWindow(const InheritFrom, NewName: String): TAHMPluginWindow;
    function GetPluginWindow(const Name: String): TAHMPluginWindow;
    procedure PopulateDefaultObjects; override;
  end;


implementation

uses
  SysUtils, ApplicationManager, UIControls, Canvas, Colour, ErrorCodes,
  TagNames, XMLTags;

constructor TAHMPluginWindowList.Create;
begin
  inherited Create;

  XMLTagName := TAG_PLUGINWINDOWS;
  ChildClass := TAHMPluginWindow;
end;

function TAHMPluginWindowList.AddPluginWindow(const InheritFrom, NewName: String): TAHMPluginWindow;
begin
  Result := TAHMPluginWindow(Inherit(InheritFrom, NewName));
end;

function TAHMPluginWindowList.GetPluginWindow(const Name: String): TAHMPluginWindow;
begin
  Result := TAHMPluginWindow(GetObject(Name));
end;

procedure TAHMPluginWindowList.PopulateDefaultObjects;
begin
  with ApplicationManagerInstance.ThemeManager, DefaultObject as TAHMPluginWindow do
  begin
    VirtualWidth := 400;
    VirtualHeight := 400;
    Colour := TAHMColour(ThemeObjects[otColours].DefaultObject);
    Fill := TAHMFill(ThemeObjects[otFills].DefaultObject);
  end;
end;


//----------------------------------------------------------------------------//
constructor TAHMPluginWindow.Create(const Name: String);
begin
  inherited Create(Name);

  XMLTagName := TAG_PLUGINWINDOW;
  ObjectType := otPluginWindows;
  ImageIndex := Ord(otPluginWindows);

{$IFDEF DESIGNER}
  // Render preview using a plugin control
  PreviewControlClass := TAHMPluginControl;
{$ENDIF}
end;

procedure TAHMPluginWindow.ClearProperties;
begin
  inherited;

  // Clear custom plugin window properties
  FColour := nil;
  FFill := nil;
end;

procedure TAHMPluginWindow.Render(Control: TObject; iX, iY, iWidth, iHeight: Single);
begin
  // We should get passed a plugin control
  with Control as TAHMPluginControl do
  begin
    // Use control dimensions if set, then style, finally size to viewport
    if (Width <> 0) and (Height <> 0) then
      RenderRect := CanvasRect(XPos, YPos, Width, Height)
    else if (Self.Width <> 0) and (Self.Height <> 0) then
      RenderRect := CanvasRect(XPos, YPos, Self.Width, Self.Height)
    else
      RenderRect := CanvasRect(XPos, YPos, Viewport.Width - XPos, Viewport.Height - YPos);

    if Assigned(Plugin) then
    begin
      Plugin.Render;

      // Use fill shading if populated, otherwise use gamma
      if FFill <> nil then
        Plugin.RenderCache.Render(RenderRect, FFill.Shade, Gamma, XScale, YScale, HorizontalFlip, VerticalFlip)
      else
        Plugin.RenderCache.Render(RenderRect, nil, Gamma, XScale, YScale, HorizontalFlip, VerticalFlip);
    end
    else with Viewport.Canvas do
    begin
      // Default rendering without an active plugin
      if Assigned(FColour) then BrushColour := FColour.Colour
                           else BrushColour := TAHMCanvasColour.Black;

      // Use fill shading if populated, otherwise use gamma
      if FFill <> nil then
        FillRect(RenderRect, FFill.Shade, Gamma, XScale, YScale)
      else
        FillRect(RenderRect, nil, Gamma, XScale, YScale);
    end;
  end;
end;

procedure TAHMPluginWindow.SeedObject;
begin
{$IFDEF DESIGNER}
  if Ancestor = nil then
    with ApplicationManagerInstance.ThemeManager.VisualDescriptor do
    begin
      VirtualWidth := 400;
      VirtualHeight := 400;
      Colour := ColourList.GetColour(DEFAULT_WHITE_NAME);
      Fill := FillList.GetFill(DEFAULT_OBJECT_NAME);
    end;
{$ENDIF}
end;

procedure TAHMPluginWindow.Assign(Source: TPersistent);
begin
  inherited Assign(Source);

  with Source as TAHMPluginWindow do
  begin
    Self.Colour := Colour;
    Self.Fill := Fill;
  end;
end;

procedure TAHMPluginWindow.SaveXMLBody(Lines: TStrings);
var
  oAncs: TAHMPluginWindow;
begin
  // Determine which ancestor to compare against - real or empty
  oAncs := TAHMPluginWindow(ObjectToCompare);

  // Do we need to colour?
  if (FColour <> nil) and (FColour <> oAncs.Colour) then
    Lines.Add(TABS[3] + FColour.XMLReference);
  if (FFill <> nil) and (FFill <> oAncs.Fill) then
    Lines.Add(TABS[3] + FFill.XMLReference);

  // Do we need to store size?
  if ((VirtualWidth <> 0) and (VirtualWidth <> oAncs.VirtualWidth)) or
     ((VirtualHeight <> 0) and (VirtualHeight <> oAncs.VirtualHeight)) then
    Lines.Add(TABS[3] + TGB+TAG_SIZE+TGC+ IntToStr(VirtualWidth) + ',' +
              IntToStr(VirtualHeight) + TGE+TAG_SIZE+TGC);
end;

procedure TAHMPluginWindow.ParseFromXML(XML: TAHMXMLHelper);
var
  sColour, sFill: String;
  iW, iH: Integer;
  MediaNode, PropsNode: TAHMXMLNode;
begin
  // Initialise parsing nodes
  MediaNode := XML.CurrentNode;
  PropsNode := nil;

  // All media window elements are optional, so see what we have
  while XML.NextElement(MediaNode, PropsNode) do
    with ApplicationManagerInstance.ThemeManager.VisualDescriptor do
    begin
      if XML.CurrentElement = TAG_COLOUR then
      begin
        sColour := XML.GetAttribute(ATTR_NAME);
        if sColour <> '' then Colour := ColourList.GetColour(sColour);
      end
      else if (XML.CurrentElement = TAG_FILL) or
              (XML.CurrentElement = TAG_GRADEDFILL) or
              (XML.CurrentElement = TAG_LINEARFILL) then
      begin
        sFill := XML.GetAttribute(ATTR_NAME);
        if sFill <> '' then Fill := FillList.GetFill(sFill);
      end
      else if XML.CurrentElement = TAG_SIZE then
      begin
        // Get the media window size
        if not XML.GetCoordsValue(iW, iH) then
          LogParsingError(THM_PRS_VIS_MALFORMED_MW_SIZE_TAGS, Self);

        if iW <> 0 then VirtualWidth := iW;
        if iH <> 0 then VirtualHeight := iH;
      end;
    end;
end;

procedure TAHMPluginWindow.BuildProperties(Properties: TAHMUIPropertyList);
begin
{$IFDEF DESIGNER}
  inherited;

  // Build custom media window properties
  Properties.Add('Width', 'VirtualWidth', CAT_PLUGINWINDOW, HINT_WIDTH);
  Properties.Add('Height', 'VirtualHeight', CAT_PLUGINWINDOW, HINT_HEIGHT);
  Properties.Add('Colour', 'Colour', CAT_PLUGINWINDOW, HINT_COLOUR);
  Properties.Add('Fill', 'Fill', CAT_PLUGINWINDOW, HINT_FILL);
{$ENDIF}
end;

end.
